package com.raincat.multimediapicker.utils;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.raincat.multimediapicker.R;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Locale;

public class ImageController {
    /**
     * 压缩后图片最大尺寸（不建议更改）
     */
    private final static int MAXSIZE = 400;
    /**
     * 只查看图片
     */
    public static final int TAKE = 0;
    /**
     * 选择图片并裁剪
     */
    public static final int CROP = 1;
    /**
     * 模式：0.只选择图片 1.选择图片并裁剪
     */
    public static int Mode = 0;
    /**
     * 裁剪输出大小，默认300
     */
    public static int outputX = 300;
    public static int outputY = 300;
    /**
     * 图片选择数量，默认为1
     */
    public static int maxCount = 1;
    /**
     * 是否显示拍照
     */
    public static boolean showCameraOption = false;
    /**
     * 是否显示原图
     */
    public static boolean showOriginalOption = false;
    /**
     * 是否返回原图
     */
    public static boolean isOriginal = false;

    // 对外开放的列表，一个压缩后图片路径集，一个原始图片路径集
    public static ArrayList<String> zoomPathList = new ArrayList<>();
    public static ArrayList<String> realPathList = new ArrayList<>();
    public static LinkedHashMap<String, ImageItem> imageItemMap = new LinkedHashMap<>();
    public static int count = 0;

    private static float imageSize = 0f;
    private static int imageIndex = 0;

    static void initController(PickerConfig pickerConfig) {
        Mode = pickerConfig.mode;
        if (Mode == CROP)
            maxCount = 1;
        else
            maxCount = pickerConfig.maxCount;
        outputX = pickerConfig.outputX;
        outputY = pickerConfig.outputY;
        showCameraOption = pickerConfig.showCameraOption;
        showOriginalOption = pickerConfig.showOriginalOption;
    }

    /**
     * 把选中图片放入或移出临时Map
     *
     * @param context   context
     * @param imageItem 图片对象
     * @return 添加返回true，移出返回false
     */
    public static boolean addOrRemoveImageItem(Context context, ImageItem imageItem) {
        if (imageItemMap.get(imageItem.imagePath) != null) {
            imageItemMap.remove(imageItem.imagePath);
            count--;
            imageSize = imageSize - imageItem.imageSize;
            return false;
        } else if (count < maxCount) {
            imageItemMap.put(imageItem.imagePath, imageItem);
            count++;
            imageSize = imageSize + imageItem.imageSize;
            return true;
        }
        Toast.makeText(context, context.getResources().getString(R.string.picker_select_tips1) + maxCount + context.getResources().getString(R.string.picker_select_tips2), Toast.LENGTH_SHORT).show();
        return false;
    }

    /**
     * 根据path移除选中的图片
     *
     * @param context context
     * @param path    图片路径
     * @return 添加返回true，移出返回false
     */
    public static boolean addOrRemoveImageItem(Context context, String path) {
        ImageItem imageitem = new ImageItem();
        imageitem.imagePath = path;
        imageitem.imageSize = ImageCacheUtils.getFileSize(path);
        return addOrRemoveImageItem(context, imageitem);
    }

    /**
     * 返回真实图片路径集
     */
    public static void takeRealPathList() {
        realPathList.clear();
        for (ImageItem imageItem : imageItemMap.values()) {
            realPathList.add(imageItem.imagePath);
        }
    }

    /**
     * 缩小图片集
     */
    public static void takeZoomPathList(final Context context, final OnAllDecodeListener listener) {
        imageIndex = 0;
        takeRealPathList();
        final ProgressDialog dialog = ProgressDialog.show(context, null, context.getResources().getString(R.string.picker_now_loading_please_wait));
        final ImageCacheUtils imageCacheUtils = new ImageCacheUtils(context);
        for (ImageItem imageItem : imageItemMap.values()) {
            decodeBitmap(context, imageItem, new OnDecodeListener() {
                @Override
                public void onResult(String path, Bitmap bm) {
                    if (bm != null) {
                        imageCacheUtils.addBitmapToFile(path, 80, bm);
                        imageItemMap.get(path).imageZoomPath = imageCacheUtils.getCachePath(path);
                    } else if (imageItemMap.get(path).imageZoomPath.length() == 0)
                        imageItemMap.get(path).imageZoomPath = path;

                    imageIndex++;
                    if (imageIndex == imageItemMap.size()) {
                        zoomPathList.clear();
                        for (ImageItem imageItem : imageItemMap.values()) {
                            zoomPathList.add(imageItem.imageZoomPath);
                        }
                        dialog.dismiss();
                        listener.onResult();
                    }
                }
            });
        }

    }

    private static synchronized void decodeBitmap(Context context, final ImageItem imageItem, final OnDecodeListener b) {
        if (imageItem.imageSuffix.equalsIgnoreCase("gif"))
            b.onResult(imageItem.imagePath, null);
        else if (imageItem.imageZoomPath.length() != 0) {
            b.onResult(imageItem.imagePath, null);
        } else {
            try {
                BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File(imageItem.imagePath)));
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeStream(in, null, options);
                in.close();

                int reqWidth, reqHeight;
                if (options.outHeight < options.outWidth) {
                    reqWidth = MAXSIZE;
                    reqHeight = MAXSIZE * options.outWidth / options.outHeight;
                } else {
                    reqHeight = MAXSIZE;
                    reqWidth = MAXSIZE * options.outHeight / options.outWidth;
                }

                if (context != null) {
                    if (((Activity) context).isFinishing())
                        return;
                    Glide.with(context).asBitmap().load(imageItem.imagePath).into(new SimpleTarget<Bitmap>(reqWidth, reqHeight) {
                        @Override
                        public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                            b.onResult(imageItem.imagePath, resource);
                        }
                    });
                }
            } catch (ClassCastException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private interface OnDecodeListener {
        void onResult(String path, Bitmap bm);
    }

    public interface OnAllDecodeListener {
        void onResult();
    }

    public static String getImageSize() {
        if (imageSize == 0)
            return "";
        else if (imageSize / 1024 < 1000)
            return "(" + String.format(Locale.getDefault(), "%.2f", imageSize / 1024) + "K)";
        else
            return "(" + String.format(Locale.getDefault(), "%.2f", imageSize / 1024 / 1024) + "M)";
    }

    static void reset() {
        zoomPathList.clear();
        realPathList.clear();
        imageItemMap.clear();
        count = 0;
        imageSize = 0f;
        imageIndex = 0;
    }
}
